<template>
    <el-dialog
        class="CustomCPM"
        :visible.sync="visibleSync"
        :destroy-on-close="true"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
        :show-close="showClose"
        :append-to-body="true"
        :width="width || '500px'"
    >
        <template slot="title">
            <span style="font-size: 14px; font-weight: bold">
                {{ title || '系统提醒' }}
            </span>
        </template>
        <template>
            <div class="contentView">
                <slot :name="slotName || 'default'" :data="data">
                    <div class="content">
                        {{ content }}
                    </div>
                </slot>
            </div>
        </template>
        <template slot="footer">
            <div class="message-footer">
                <div v-if="!hideCancel || !hideConfirm">
                    <el-button v-if="!hideCancel" class="footer-button" @click="buttonEvent(false)">
                        {{ cancelText || '取消' }}
                    </el-button>
                    <el-button v-if="!hideConfirm" class="footer-button" type="primary" @click="buttonEvent(true)">
                        {{ confirmText || '继续' }}
                    </el-button>
                </div>
                <slot name="footer" />
            </div>
        </template>
    </el-dialog>
</template>

<script lang="ts">
import Component from 'vue-class-component';
import Vue from 'vue';
let waitTask = Object.create(null);
@Component({
    name: 'Message'
})
export default class App extends Vue {
    data: any = null;
    visibleSync: boolean = false;
    width: any = null;
    content: string = '';
    callback: any = null;
    hideTitle: boolean = false;
    title: string = '';
    slotName: string = '';
    cancelText: string = '';
    confirmText: string = '';
    hideCancel: boolean = false;
    hideConfirm: boolean = false;
    // 显示关闭按钮
    showClose: boolean = false;
    // 是否手动关闭
    handelClose: boolean = false;
    // 回调异步等待
    wait: boolean = false;
    $ViewMessage(object) {
        // eslint-disable-next-line no-async-promise-executor
        return new Promise(async (resolve) => {
            const key = [
                'width',
                'hideTitle',
                'title',
                'callback',
                'slotName',
                'content',
                'cancelText',
                'confirmText',
                'hideCancel',
                'hideConfirm',
                'showClose',
                'data',
                'handelClose'
            ];
            for (let a = 0; a < key.length; a++) {
                const item = key[a];
                object[item] &&
                    object[item].toString().length > 0 &&
                    (await (async () => {
                        if (!~['symbol', 'function'].indexOf(typeof object[item])) {
                            this.$data[item] = await this.structuralClone(object[item]);
                        } else {
                            this.$data[item] = object[item];
                        }
                    })());
            }
            waitTask = this.factoryFun(); // 初始化对象 劫持解除
            this.visibleSync = true;
            // eslint-disable-next-line accessor-pairs
            Object.defineProperty(waitTask, 'status', {
                set() {
                    resolve();
                }
            });
        });
    }

    async buttonEvent(boolean) {
        const data = await this.structuralClone(this.data);
        if (this.callback) {
            (await this.callback(boolean, data)) &&
                (() => {
                    waitTask.status = true;
                    this.close();
                })();
        } else {
            this.close();
        }
    }

    factoryFun() {
        return {
            status: false,
            returnValue: false
        };
    }

    close() {
        // typescript 不支持this.$options.data()
        this.data = null;
        this.visibleSync = false;
        this.width = null;
        this.content = '';
        this.callback = null;
        this.hideTitle = false;
        this.title = '';
        this.slotName = '';
        this.cancelText = '';
        this.confirmText = '';
        this.hideCancel = false;
        this.hideConfirm = false;
        this.showClose = false;
        this.handelClose = false;
        this.wait = false;
    }
    structuralClone(obj) {
        return new Promise((resolve) => {
            const { port1, port2 } = new MessageChannel();
            port2.onmessage = (ev) => resolve(ev.data);
            port1.postMessage(obj);
        });
    }
}
</script>
<style scoped lang="scss">
.message-footer {
    display: flex;
    justify-content: flex-end;
    align-items: center;
}
.contentView {
    max-height: 50vh;
}
.content {
    min-height: 60px;
    padding-left: 20px;
}

.footer-button {
    height: 30px;
    width: 80px;
}
</style>
<style lang="scss">
.CustomCPM {
    .el-dialog__footer {
        padding: 8px;
    }
    .el-dialog__header {
        /*padding: 10px 20px !important;*/
        .el-dialog__headerbtn {
            top: 15px !important;
        }
        border-bottom: 1px #dfd6d0 solid;
    }
    .el-dialog__body {
        padding: 0 !important;
    }
}
</style>
